﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVL;
using System.Xml;
using General;

namespace TVLL5A
{
    public class NPCL5A : NPC
    {
        private string _Status;
        private string _Clan;
        private int _Resistencia;
        private int _Voluntad;
        private int _Fuerza;
        private int _Percepcion;
        private int _Agilidad;
        private int _Inteligencia;
        private int _Reflejos;
        private int _Consciencia;
        private int _Vacio;
        private int _Tierra;
        private int _Agua;
        private int _Fuego;
        private int _Aire;
        private string _Escuela;
        private int _Reconocimiento;
        private List<HabilidadesL5A> _Habilidades;
        private List<TecnicaHechizoL5A> _Hechizos;
        private int _DañoActual;
        private float _Honor;
        private float _Gloria;
        private int _ManchaSombria;
        private const string _juego = "L5A";
        private const string _rutaxsd = "../../../TVLL5A/NPCL5A.xsd";
        protected string _fallo;
       
        public NPCL5A()
        {
            _Resistencia = _Voluntad = _Fuerza = _Percepcion = _Agilidad
                = _Inteligencia = _Reflejos = _Consciencia = _Vacio = _Tierra = _Agua
                = _Fuego = _Aire = _Reconocimiento = _DañoActual = _ManchaSombria = 0;
            _Status = _Clan = _Escuela = _fallo = "";
            _Honor = _Gloria = 0.0f;
            _Habilidades = new List<HabilidadesL5A>();
            _Hechizos = new List<TecnicaHechizoL5A>();
            _fallo = "No";

        }

        public NPCL5A(XmlElement nodo)
        {
            _fallo = "No";
            _Habilidades = new List<HabilidadesL5A>();
            _Hechizos = new List<TecnicaHechizoL5A>();
            this.cargar(nodo);
        }

        public NPCL5A(string ruta)
        {
            _fallo = "No";
            _Habilidades = new List<HabilidadesL5A>();
            _Hechizos = new List<TecnicaHechizoL5A>();
            this.cargar(ruta);
        }

        public string Status
        {
            get
            {
                return this._Status;
            }
            set
            {
                this._Status = value;
            }
        }

        public string Clan
        {
            get
            {
                return this._Clan;
            }
            set
            {
                this._Clan = value;
            }
        }

        public int Resistencia
        {
            get
            {
                return this._Resistencia;
            }
            set
            {
                this._Resistencia = value;
            }
        }

        public int Voluntad
        {
            get
            {
                return this._Voluntad;
            }
            set
            {
                this._Voluntad = value;
            }
        }

        public int Fuerza
        {
            get
            {
                return this._Fuerza;
            }
            set
            {
                this._Fuerza = value;
            }
        }

        public int Percepcion
        {
            get
            {
                return this._Percepcion;
            }
            set
            {
                this._Percepcion = value;
            }
        }

        public int Agilidad
        {
            get
            {
                return this._Agilidad;
            }
            set
            {
                this._Agilidad = value;
            }
        }

        public int Inteligencia
        {
            get
            {
                return this._Inteligencia;
            }
            set
            {
                this._Inteligencia = value;
            }
        }

        public int Reflejos
        {
            get
            {
                return this._Reflejos;
            }
            set
            {
                this._Reflejos = value;
            }
        }

        public int Consciencia
        {
            get
            {
                return this._Consciencia;
            }
            set
            {
                this._Consciencia = value;
            }
        }

        public int Vacio
        {
            get
            {
                return this._Vacio;
            }
            set
            {
                this._Vacio = value;
            }
        }

        public string Escuela
        {
            get
            {
                return this._Escuela;
            }
            set
            {
                this._Escuela = value;
            }
        }

        public int Reconocimiento
        {
            get
            {
                return this._Reconocimiento;
            }
            set
            {
                this._Reconocimiento = value;
            }
        }

        public int Tierra
        {
            get
            {
                return this._Tierra;
            }
            set
            {
                this._Tierra = value;
            }
        }

        public int Agua
        {
            get
            {
                return this._Agua;
            }
            set
            {
                this._Agua = value;
            }
        }

        public int Aire
        {
            get
            {
                return this._Aire;
            }
            set
            {
                this._Aire = value;
            }
        }

        public int Fuego
        {
            get
            {
                return this._Fuego;
            }
            set
            {
                this._Fuego = value;
            }
        }

        public List<HabilidadesL5A> Habilidades
        {
            get
            {
                return this._Habilidades;
            }
            set
            {
                this._Habilidades = value;
            }
        }

        public List<TecnicaHechizoL5A> Hechizos
        {
            get { return this._Hechizos; }
            set { this._Hechizos = value; }
        }

        public int DañoActual
        {
            get
            {
                return this._DañoActual;
            }
            set
            {
                this._DañoActual = value;
            }
        }

        public float Gloria
        {
            get
            {
                return this._Gloria;
            }
            set
            {
                this._Gloria = value;
            }
        }

        public float Honor
        {
            get
            {
                return this._Honor;
            }
            set
            {
                this._Honor = value;
            }
        }

        public int ManchaSombria
        {
            get
            {
                return this._ManchaSombria;
            }
            set
            {
                this._ManchaSombria = value;
            }
        }

        public string Fallo
        {
            get { return this._fallo; }
        }

        public override void toXTVL(XmlTextWriter mixml)
        {
            mixml.WriteStartElement("personaje");
            mixml.WriteAttributeString("juego", "L5A");
            mixml.WriteAttributeString("personaje", "NPC");
            mixml.WriteAttributeString("tipo", "NPC");
            mixml.WriteElementString("nombre", this.Nombre);
            mixml.WriteElementString("bio", this.Bio);
            mixml.WriteElementString("status", this.Status);
            mixml.WriteElementString("clan", this.Clan);
            mixml.WriteStartElement("atributos");
            mixml.WriteElementString("resistencia", this.Resistencia.ToString());
            mixml.WriteElementString("voluntad", this.Voluntad.ToString());
            mixml.WriteElementString("fuerza", this.Fuerza.ToString());
            mixml.WriteElementString("percepcion", this.Percepcion.ToString());
            mixml.WriteElementString("agilidad", this.Agilidad.ToString());
            mixml.WriteElementString("inteligencia", this.Inteligencia.ToString());
            mixml.WriteElementString("reflejos", this.Reflejos.ToString());
            mixml.WriteElementString("consciencia", this.Consciencia.ToString());
            mixml.WriteElementString("vacio", this.Vacio.ToString());
            mixml.WriteEndElement();
            mixml.WriteStartElement("habilidades");
            for (int i = 0; i < this.Habilidades.Count; i++)
            {
                this.Habilidades[i].toXTVL(mixml);
            }
            mixml.WriteEndElement();
            mixml.WriteStartElement("hechizos");
            for (int i = 0; i < this.Hechizos.Count; i++)
            {
                this.Hechizos[i].toXTVL(mixml);
            }
            mixml.WriteEndElement();
            mixml.WriteElementString("daño_actual", this.DañoActual.ToString());
            mixml.WriteElementString("honor", this.Honor.ToString());
            mixml.WriteElementString("gloria", this.Gloria.ToString());
            mixml.WriteElementString("mancha_sombria", this.ManchaSombria.ToString());
            this.Inventario.toXTVL(mixml);
            mixml.WriteEndElement();
        }

        public override bool guardar(string ruta)
        {
            XmlTextWriter mixml = new XmlTextWriter(ruta, System.Text.Encoding.UTF8);
            mixml.Formatting = System.Xml.Formatting.Indented;
            mixml.WriteStartDocument();
            this.toXTVL(mixml);
            mixml.WriteEndDocument();
            mixml.Close();
            XSDValidator validador = new XSDValidator(_rutaxsd, ruta);
            if (validador.validar())
            {
                return true;
            }
            else
            {
                if (System.IO.File.Exists(ruta))
                {
                    System.IO.File.Delete(ruta);
                }
                return false;
            }
        }

        public override bool cargar(string ruta)
        {
            XSDValidator validador = new XSDValidator(_rutaxsd, ruta);
            if (!validador.validar())
            {
                validador.validar();
                return false;
            }
            else
            {
                XmlDocument xtvl = new XmlDocument();
                xtvl.Load(ruta);
                XmlNodeList nombre = xtvl.GetElementsByTagName("nombre");
                XmlNodeList bio = xtvl.GetElementsByTagName("bio");
                XmlNodeList status = xtvl.GetElementsByTagName("status");
                XmlNodeList clan = xtvl.GetElementsByTagName("clan");
                XmlNodeList habilidades = xtvl.GetElementsByTagName("habilidad");
                XmlNodeList hechizos = xtvl.GetElementsByTagName("hechizos");
                this.Nombre = nombre[0].InnerText;
                this.Bio = bio[0].InnerText;
                this.Status = status[0].InnerText;
                this.Clan = clan[0].InnerText;
                foreach (XmlElement nodo in habilidades)
                {
                    HabilidadesL5A hab = new HabilidadesL5A(nodo);
                    this.Habilidades.Add(hab);
                }
                foreach (XmlElement nodo in hechizos)
                {
                    TecnicaHechizoL5A hech = new TecnicaHechizoL5A(nodo);
                    this.Hechizos.Add(hech);
                }
                XmlNodeList daño = xtvl.GetElementsByTagName("daño_actual");
                XmlNodeList honor = xtvl.GetElementsByTagName("honor");
                XmlNodeList gloria = xtvl.GetElementsByTagName("gloria");

                this.DañoActual = Convert.ToInt32(daño[0].InnerText);
                this.Honor = Convert.ToSingle(honor[0].InnerText);
                this.Gloria = Convert.ToSingle(gloria[0].InnerText);

                XmlNodeList invent = xtvl.GetElementsByTagName("inventario");

                foreach (XmlElement nodo in invent)
                {
                    XmlNodeList pasta = nodo.GetElementsByTagName("dinero");
                    foreach (XmlElement np in pasta)
                    {
                        DineroL5A npasta = new DineroL5A(np);
                        Inventario.Dinero = npasta;
                    }
                    XmlNodeList cosa = nodo.GetElementsByTagName("objeto");
                    foreach (XmlElement ncosa in cosa)
                    {
                        if (ncosa.Name == "objeto")
                        {
                            ArmaL5A narma = new ArmaL5A();
                            if (!narma.cargar(ncosa))
                            {
                                Objeto nobj = new Objeto(ncosa);
                                Inventario.Añadir(nobj);
                            }
                            else
                            {
                                Inventario.Añadir(narma);
                            }
                        }
                    }
                }
                
                return true;
            }
        }

        public override bool cargar(XmlElement nodo)
        {
            try
            {
                XmlNodeList nombre = nodo.GetElementsByTagName("nombre");
                XmlNodeList bio = nodo.GetElementsByTagName("bio");
                XmlNodeList status = nodo.GetElementsByTagName("status");
                XmlNodeList clan = nodo.GetElementsByTagName("clan");
                XmlNodeList habilidades = nodo.GetElementsByTagName("habilidad");
                XmlNodeList hechizos = nodo.GetElementsByTagName("hechizo");

                this.Nombre = nombre[0].InnerText;
                this.Bio = bio[0].InnerText;
                this.Status = status[0].InnerText;
                this.Clan = clan[0].InnerText;

                foreach (XmlElement nod in habilidades)
                {
                    HabilidadesL5A hab = new HabilidadesL5A(nod);
                    this.Habilidades.Add(hab);
                }

                foreach (XmlElement nod in hechizos)
                {
                    TecnicaHechizoL5A hech = new TecnicaHechizoL5A(nod);
                    this.Hechizos.Add(hech);
                }

                XmlNodeList daño = nodo.GetElementsByTagName("daño_actual");
                XmlNodeList honor = nodo.GetElementsByTagName("honor");
                XmlNodeList gloria = nodo.GetElementsByTagName("gloria");

                this.DañoActual = Convert.ToInt32(daño[0].InnerText);
                this.Honor = Convert.ToSingle(honor[0].InnerText);
                this.Gloria = Convert.ToSingle(gloria[0].InnerText);

                XmlNodeList invent = nodo.GetElementsByTagName("inventario");

                foreach (XmlElement nod in invent)
                {
                    XmlNodeList pasta = nod.GetElementsByTagName("dinero");
                    foreach (XmlElement np in pasta)
                    {
                        DineroL5A npasta = new DineroL5A(np);
                        Inventario.Dinero = npasta;
                    }
                    XmlNodeList cosa = nod.GetElementsByTagName("objeto");
                    foreach (XmlElement ncosa in cosa)
                    {
                        if (ncosa.Name == "objeto")
                        {
                            ArmaL5A narma = new ArmaL5A();
                            if (!narma.cargar(ncosa))
                            {
                                Objeto nobj = new Objeto(ncosa);
                                Inventario.Añadir(nobj);
                            }
                            else
                            {
                                Inventario.Añadir(narma);
                            }
                        }
                    }
                }

                return true;
            }
            catch(Exception ex)
            {
                this._fallo = ex.Message;
                return false;
            }
        }
    }
}
